package com.wjx;

import com.wjx.reflection.AutoWired;
import com.wjx.reflection.UserController;
import com.wjx.reflection.UserService;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.stream.Stream;

/**
 *  反射
 */
public class Main {

    public static void main(String[] args) {
	// write your code here
       // fillAttributeBySet();
        fillAttributeByAnnotation();
    }

    /**
     * 采用反射-通过set方法的方式 注入bean
     */
    public static void fillAttributeBySet(){
        UserController userController = new UserController();
        Class<?> clazz = userController.getClass();
        UserService userService = new UserService();

        try {
            Field userServiceField = clazz.getDeclaredField("userService");
            // 设置可以访问到私有属性
            userServiceField.setAccessible(true);
            // 通过set属性进行赋值
            String name = userServiceField.getName();
            //拼接方法名称
            name = name.substring(0,1).toUpperCase() + name.substring(1,name.length());
            String setMethodName = "set" + name;
            // 通过方法注入属性对象
            Method method = clazz.getMethod(setMethodName,UserService.class);
            //反射
            method.invoke(userController,userService);

            System.out.println(userController.getUserService());

        } catch (NoSuchFieldException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 采用反射-通过注解的方法的方式 注入bean
     */
    public static void fillAttributeByAnnotation(){
        UserController userController = new UserController();
        Class<? extends UserController> clazz = userController.getClass();

        Stream.of(clazz.getDeclaredFields()).forEach(field -> {
           AutoWired autoWired = field.getAnnotation(AutoWired.class);
           if (autoWired != null){
               field.setAccessible(true);
               Class type = field.getType();
               try {
                   Object o = type.newInstance();
                   field.set(userController,o);
               } catch (InstantiationException e) {
                   e.printStackTrace();
               } catch (IllegalAccessException e) {
                   e.printStackTrace();
               }
           }
        });
        System.out.println(userController.getUserDao());
    }

}
